松本行弘的程序世界 11 程序安全性
程序的漏洞与攻击方法
四种软件漏洞
- dos攻击
- 信息泄露
- 权限夺取
- 权限升格
DOS攻击,即拒绝服务攻击,指妨碍软件正常运行(服务的执行)的网络攻击手段。能够引起软件异常终止的程序错误,全部都是引发DOS攻击的安全性程序错误。
分为软件漏洞与外部DOS攻击。
信息泄露指不愿公开的信息被公开了。
因权限被窃取而成为重大问题
安全问题的根源
在于运行软件的人(权限所有者)和利用软件的人是不同的。
安全问题有三种
- 恶意软件
指在程序本身植入了恶意代码。 - setuid/setgid
指执行的程序以所有者权限进行动作。setuid的缺点已经变得比优点更突出,现在几乎不用了。 - 服务器
“守护神”引起的问题
服务这里指的是为了提供服务而常驻型的软件,又为后台服务(daemon),即守护神的意思。
后台服务基本上都是受理经由socket而来的请求。执行它所提供的服务,将结果经socket返回。几乎所有的情况,发出请求者和执行权限者都是不同的。这种软件若有了漏洞,会引起DOS问题和权限夺取问题。
多样化的攻击手段
代表性的有:
- 缓冲区溢出
- 整数溢出
- 跨站点脚本攻击(XSS)
- SQL注入
- 跨站点伪造请求(CSRF)
缓冲区溢出
指向固定的缓冲区输入了比假定长度要长很多的数据,使程序异常终止。或者是更改堆栈的跳转地址劫持程序。
使用C那种连数组长度都不检查的语言,可以说肯定会产生问题。幸亏,像Ruby这样的高级语言,语言处理系统自动分配内存,可以不使用固定长的缓冲区。使用更高级的语言,可以从缓冲区溢出问题中解放出来。但由于速度上的考虑,还会开发C语言的CGI及Daemon程序,应多加注意。
整数溢出
整数溢出与缓冲区溢出相似,但它是更难被发现的问题。
c等很多语言,整数只能表示一定范围的数,超过范围,就会发生溢出,也不发出警告就将数值舍入。这个问题通过使用Ruby这样的高级语言可以解决,内存分配不是由用户直接进行,内部分配都要经过严格检查。所以,只要使用Ruby,与整数溢出就不沾边。
SQL注入
SQL注入是对外部的输入检查不充分时所产生的典型问题。
从外部的输入不能原封不动填到SQL语句中去,因为填入的文字可能含有对SQL语句有某种意义的文字。
Shell注入
Shell注入与SQL注入原理相同。
从外部的输入,如果不进行检查就不能传递给system等危险的函数。
为了从一定程度上检查出这类问题,Ruby和Perl中有“污染检查”功能。给外部输入的数据加上“污染记号”,禁止对字符串进行危险操作。
跨站点脚本攻击
跨站点脚本攻击与SQL注入和Shell注入一样,也是因为将输入值原封不动地放在输出值内而引起的问题。
如用户输入中含有HTML标签。而且HTML可能夹杂JavaScript。
跨站点伪造请求
跨站点伪造请求(CSRF)是Web应用程序固有的攻击手段。
构成Web应用程序的每一页由两部分构成,一个来自网路浏览器的HTTP请求,一个是HTTP服务器的响应。
社会工程
用异常进行错误处理
异常的历史
Java的受控异常
采用受控异常的,Java是第一个。
Icon的面向目标判断
Ruby在设计之初,也曾认真考虑过采用像Icon式的真伪值判断,结果还是采用了nil和false以外的值全是真值的这种正统方式。
Ruby的异常
异常发生
异常处理的设计方针
方法的执行应当“异常安全”,即执行时及时发生了异常也不会发生异常情况:
- 因为发生了异常,留下了不完全的数据结构
- 因为发生了异常,数据库里进了垃圾
- 因为发生了异常,程序异常终止
异常发生的设计原则
假设发生的情况与既有的异常类明显不同,需要制作一个新的异常。此时考虑:
- 名称:应该给新的类起一个什么样的名字
- 父类:新的类应该属于哪一个异常类的子类
- 生成方法:应该如何初始化新的类实例
产生异常的两个原则:1异步异常,基本原则是不要使用异步异常。2.文档化,有必要清楚详细的写成文档。